package com.sunagy.demand.backend.utils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import com.sunagy.demand.backend.VO.ResultVO;
import com.sunagy.demand.backend.enums.BuzEnum;
import com.sunagy.demand.backend.exception.BuzException;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.*;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Map;

/**
 * desc：#TODO fill me ！
 * author：三餘無夢生
 * date：2018/4/27
 * time：下午5:44
 */
@Slf4j
public class HttpsUtil {
    private static Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();

    private static CloseableHttpClient httpclient;

    static {
        try {
            SSLContext sslContext = SSLContext.getInstance("TLSv1");

            // 实现一个X509TrustManager接口，用于绕过验证，不用修改里面的方法
            X509TrustManager trustManager = new X509TrustManager() {
                public void checkClientTrusted(
                        java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
                        String paramString) throws CertificateException {
                }

                public void checkServerTrusted(
                        java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
                        String paramString) throws CertificateException {
                }
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            };

            sslContext.init(null, new TrustManager[] { trustManager }, null);
            SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
                    sslContext);
            httpclient = HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
        } catch (NoSuchAlgorithmException e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.PARAMS_INCORRECT);
        } catch (KeyManagementException e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.PARAMS_INCORRECT);
        }
    }

    public static JsonObject execute(HttpUriRequest request){
        try {
            HttpResponse res = httpclient.execute(request);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>"+ request.getURI()  + "\r\nresponse=>" + jsonStr);
            if(res.getStatusLine().getStatusCode() == 200){
                JsonObject obj = gson.fromJson(jsonStr, JsonObject.class);
                return obj;
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (JsonSyntaxException e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.ClASS_TYPE_ERROR);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T> T execute(HttpUriRequest request, Class<T> clazz){
        try {
            HttpResponse res = httpclient.execute(request);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>"+ request.getURI()  + "\r\nresponse=>" + jsonStr);
            if(res.getStatusLine().getStatusCode() == 200){
                T response = gson.fromJson(jsonStr, clazz);
                return response;
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (JsonSyntaxException e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.ClASS_TYPE_ERROR);
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T extends ResultVO> T post(String url, String body, Class<T> clazz) {
        HttpPost httpPost = new HttpPost(url);
        try {
            httpPost.setEntity(new StringEntity(body, "UTF-8"));
            HttpResponse res = httpclient.execute(httpPost);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>" + url + "\n\nbody=>" + body + "\r\nresponse=>" + jsonStr);
            if(res.getStatusLine().getStatusCode() == 200){
                Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
                JsonObject data = gson.fromJson(jsonStr, JsonObject.class);
                if(data.has("code") && data.get("code").getAsInt() == 0){
                    T response = gson.fromJson(data.get("message"), clazz);
                    response.setCode(data.get("code").getAsInt());
                    return response;
                }else{
                    T response = clazz.newInstance();
                    response.setCode(data.get("code").getAsInt());
                    response.setMsg(data.get("message").getAsString());
                    return response;
                }
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T extends ResultVO> T post(String url, Class<T> clazz) {
        HttpPost httpPost = new HttpPost(url);
        try {
            httpPost.setEntity(new StringEntity("", "UTF-8"));
            HttpResponse res = httpclient.execute(httpPost);

            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>" + url + "\r\nresponse=>" + jsonStr);
            if(res.getStatusLine().getStatusCode() == 200){
                JsonObject data = gson.fromJson(jsonStr, JsonObject.class);
                if(data.has("code") && data.get("code").getAsInt() == 0){
                    T response = gson.fromJson(data.get("message"), clazz);
                    response.setCode(data.get("code").getAsInt());
                    return response;
                }else{
                    T response = clazz.newInstance();
                    response.setCode(data.get("code").getAsInt());
                    response.setMsg(data.get("message").getAsString());
                    return response;
                }
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T extends ResultVO> T post(String url, Class<T> clazz, Map<String, String> params) {
        StringBuilder builder = new StringBuilder(url);
        if(url.contains("?") && params != null){
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.append("&");
                builder.append(entry.getKey());
                builder.append("=");
                builder.append(entry.getValue());
            }
        }else if(!url.contains("?") && params != null){
            builder.append("?");
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.append("&");
                builder.append(entry.getKey());
                builder.append("=");
                builder.append(entry.getValue());
            }
        }

        HttpPost httpPost = new HttpPost(builder.toString());
        try {
            httpPost.setEntity(new StringEntity("", "UTF-8"));
            HttpResponse res = httpclient.execute(httpPost);

            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>" + url + "\r\nresponse=>" + jsonStr);
            if(res.getStatusLine().getStatusCode() == 200){
                JsonObject data = gson.fromJson(jsonStr, JsonObject.class);
                if(data.has("code") && data.get("code").getAsInt() == 0){
                    T response = gson.fromJson(data.get("message"), clazz);
                    response.setCode(data.get("code").getAsInt());
                    return response;
                }else{
                    T response = clazz.newInstance();
                    response.setCode(data.get("code").getAsInt());
                    response.setMsg(data.get("message").getAsString());
                    return response;
                }
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T extends ResultVO> T put(String url, String body, Class<T> clazz) {
        HttpPut httpPut = new HttpPut(url);
        try {
            httpPut.setEntity(new StringEntity(body, "UTF-8"));
            HttpResponse res = httpclient.execute(httpPut);

            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>" + url + "\n\nbody=>" + body + "\r\nresponse=>" + jsonStr);
            if(res.getStatusLine().getStatusCode() == 200){
                JsonObject data = gson.fromJson(jsonStr, JsonObject.class);
                if(data.has("code") && data.get("code").getAsInt() == 0){
                    T response = gson.fromJson(data.get("message"), clazz);
                    response.setCode(data.get("code").getAsInt());
                    return response;
                }else{
                    T response = clazz.newInstance();
                    response.setCode(data.get("code").getAsInt());
                    response.setMsg(data.get("message").getAsString());
                    return response;
                }
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T extends ResultVO> T put(String url, Class<T> clazz) {
        HttpPut httpPut = new HttpPut(url);
        try {
            httpPut.setEntity(new StringEntity("", "UTF-8"));
            HttpResponse res = httpclient.execute(httpPut);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>"+ url + "\r\nresponse=>" + jsonStr);

            if(res.getStatusLine().getStatusCode() == 200){
                JsonObject data = gson.fromJson(jsonStr, JsonObject.class);
                if(data.has("code") && data.get("code").getAsInt() == 0){
                    T response = gson.fromJson(data.get("message"), clazz);
                    response.setCode(data.get("code").getAsInt());
                    return response;
                }else{
                    T response = clazz.newInstance();
                    response.setCode(data.get("code").getAsInt());
                    response.setMsg(data.get("message").getAsString());
                    return response;
                }
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T extends ResultVO> T put(String url, Class<T> clazz, Map<String, String> params) {
        StringBuilder builder = new StringBuilder(url);
        if(url.contains("?") && params != null){
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.append("&");
                builder.append(entry.getKey());
                builder.append("=");
                builder.append(entry.getValue());
            }
        }else if(!url.contains("?") && params != null){
            builder.append("?");
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.append("&");
                builder.append(entry.getKey());
                builder.append("=");
                builder.append(entry.getValue());
            }
        }
        HttpPut httpPut = new HttpPut(builder.toString());
        try {
            httpPut.setEntity(new StringEntity("", "UTF-8"));
            HttpResponse res = httpclient.execute(httpPut);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>"+ url + "\r\nresponse=>" + jsonStr);

            if(res.getStatusLine().getStatusCode() == 200){
                JsonObject data = gson.fromJson(jsonStr, JsonObject.class);
                if(data.has("code") && data.get("code").getAsInt() == 0){
                    T response = gson.fromJson(data.get("message"), clazz);
                    response.setCode(data.get("code").getAsInt());
                    return response;
                }else{
                    T response = clazz.newInstance();
                    response.setCode(data.get("code").getAsInt());
                    response.setMsg(data.get("message").getAsString());
                    return response;
                }
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T extends ResultVO> T delete(String url, Class<T> clazz) {
        HttpDelete httpDelete = new HttpDelete(url);
        try {
            HttpResponse res = httpclient.execute(httpDelete);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>"+ url + "\r\nresponse=>" + jsonStr);

            if(res.getStatusLine().getStatusCode() == 200){
                JsonObject data = gson.fromJson(jsonStr, JsonObject.class);
                if(data.has("code") && data.get("code").getAsInt() == 0){
                    T response = gson.fromJson(data.get("message"), clazz);
                    response.setCode(data.get("code").getAsInt());
                    return response;
                }else{
                    T response = clazz.newInstance();
                    response.setCode(data.get("code").getAsInt());
                    response.setMsg(data.get("message").getAsString());
                    return response;
                }
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T extends ResultVO> T delete(String url, Class<T> clazz, Map<String, String> params) {
        StringBuilder builder = new StringBuilder(url);
        if(url.contains("?") && params != null){
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.append("&");
                builder.append(entry.getKey());
                builder.append("=");
                builder.append(entry.getValue());
            }
        }else if(!url.contains("?") && params != null){
            builder.append("?");
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.append("&");
                builder.append(entry.getKey());
                builder.append("=");
                builder.append(entry.getValue());
            }
        }
        HttpDelete httpDelete = new HttpDelete(builder.toString());
        try {
            HttpResponse res = httpclient.execute(httpDelete);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>"+ url + "\r\nresponse=>" + jsonStr);

            if(res.getStatusLine().getStatusCode() == 200){
                JsonObject data = gson.fromJson(jsonStr, JsonObject.class);
                if(data.has("code") && data.get("code").getAsInt() == 0){
                    T response = gson.fromJson(data.get("message"), clazz);
                    response.setCode(data.get("code").getAsInt());
                    return response;
                }else{
                    T response = clazz.newInstance();
                    response.setCode(data.get("code").getAsInt());
                    response.setMsg(data.get("message").getAsString());
                    return response;
                }
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T extends ResultVO> T get(String url, Class<T> clazz, Map<String, String> params) {
        StringBuilder builder = new StringBuilder(url);
        if(url.contains("?") && params != null){
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.append("&");
                builder.append(entry.getKey());
                builder.append("=");
                builder.append(entry.getValue());
            }
        }else if(!url.contains("?") && params != null){
            builder.append("?");
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.append("&");
                builder.append(entry.getKey());
                builder.append("=");
                builder.append(entry.getValue());
            }
        }
        HttpGet httpGet = new HttpGet(builder.toString());
        try {
            HttpResponse res = httpclient.execute(httpGet);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>"+ url + "\r\nresponse=>" + jsonStr);

            if(res.getStatusLine().getStatusCode() == 200){
                JsonObject data = gson.fromJson(jsonStr, JsonObject.class);
                if(data.has("code") && data.get("code").getAsInt() == 0){
                    T response = gson.fromJson(data.get("message"), clazz);
                    response.setCode(data.get("code").getAsInt());
                    return response;
                }else{
                    T response = clazz.newInstance();
                    response.setCode(data.get("code").getAsInt());
                    response.setMsg(data.get("message").getAsString());
                    return response;
                }
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T extends ResultVO> T get(String url, Class<T> clazz) {
        HttpGet httpGet = new HttpGet(url);
        try {
            HttpResponse res = httpclient.execute(httpGet);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>"+ url + "\r\nresponse=>" + jsonStr);

            if(res.getStatusLine().getStatusCode() == 200){
                JsonObject data = gson.fromJson(jsonStr, JsonObject.class);
                if(data.has("code") && data.get("code").getAsInt() == 0){
                    T response = gson.fromJson(data.get("message"), clazz);
                    response.setCode(data.get("code").getAsInt());
                    return response;
                }else{
                    T response = clazz.newInstance();
                    response.setCode(data.get("code").getAsInt());
                    response.setMsg(data.get("message").getAsString());
                    return response;
                }
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T> T httpPost(String url, String body, Class<T> clazz) {
        HttpPost httpPost = new HttpPost(url);
        try {
            httpPost.setEntity(new StringEntity(body, "UTF-8"));
            HttpResponse res = httpclient.execute(httpPost);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>"+ url + "\n\nbody=>" + body + "\r\nresponse=>" + jsonStr);

            if(res.getStatusLine().getStatusCode() == 200){
                T response = gson.fromJson(jsonStr, clazz);
                return response;
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T> T httpPost(String url, Class<T> clazz) {
        HttpPost httpPost = new HttpPost(url);
        try {
            httpPost.setEntity(new StringEntity("", "UTF-8"));
            HttpResponse res = httpclient.execute(httpPost);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>"+ url + "\r\nresponse=>" + jsonStr);
            if(res.getStatusLine().getStatusCode() == 200){
                T response = gson.fromJson(jsonStr, clazz);
                return response;
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T> T httpPost(String url, Class<T> clazz, Map<String, String> params) {
        StringBuilder builder = new StringBuilder(url);
        if(url.contains("?") && params != null){
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.append("&");
                builder.append(entry.getKey());
                builder.append("=");
                builder.append(entry.getValue());
            }
        }else if(!url.contains("?") && params != null){
            builder.append("?");
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.append("&");
                builder.append(entry.getKey());
                builder.append("=");
                builder.append(entry.getValue());
            }
        }

        HttpPost httpPost = new HttpPost(builder.toString());
        try {
            httpPost.setEntity(new StringEntity("", "UTF-8"));
            HttpResponse res = httpclient.execute(httpPost);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>"+ url + "\r\nresponse=>" + jsonStr);

            if(res.getStatusLine().getStatusCode() == 200){
                T response = gson.fromJson(jsonStr, clazz);
                return response;
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T> T httpPut(String url, String body, Class<T> clazz) {
        HttpPut httpPut = new HttpPut(url);
        try {
            httpPut.setEntity(new StringEntity(body, "UTF-8"));
            HttpResponse res = httpclient.execute(httpPut);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>"+ url + "\n\nbody=>" + body + "\r\nresponse=>" + jsonStr);
            if(res.getStatusLine().getStatusCode() == 200){
                T response = gson.fromJson(jsonStr, clazz);
                return response;
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T> T httpPut(String url, Class<T> clazz, Map<String, String> params) {
        StringBuilder builder = new StringBuilder(url);
        if(url.contains("?") && params != null){
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.append("&");
                builder.append(entry.getKey());
                builder.append("=");
                builder.append(entry.getValue());
            }
        }else if(!url.contains("?") && params != null){
            builder.append("?");
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.append("&");
                builder.append(entry.getKey());
                builder.append("=");
                builder.append(entry.getValue());
            }
        }
        HttpPut httpPut = new HttpPut(builder.toString());
        try {
            httpPut.setEntity(new StringEntity("", "UTF-8"));
            HttpResponse res = httpclient.execute(httpPut);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>"+ url + "\r\nresponse=>" + jsonStr);
            if(res.getStatusLine().getStatusCode() == 200){
                T response = gson.fromJson(jsonStr, clazz);
                return response;
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T> T httpPut(String url, Class<T> clazz) {
        HttpPut httpPut = new HttpPut(url);
        try {
            httpPut.setEntity(new StringEntity("", "UTF-8"));
            HttpResponse res = httpclient.execute(httpPut);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>"+ url + "\r\nresponse=>" + jsonStr);
            if(res.getStatusLine().getStatusCode() == 200){
                T response = gson.fromJson(jsonStr, clazz);
                return response;
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T> T httpDelete(String url, Class<T> clazz) {
        HttpDelete httpDelete = new HttpDelete(url);
        try {
            HttpResponse res = httpclient.execute(httpDelete);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>"+ url + "\r\nresponse=>" + jsonStr);
            if(res.getStatusLine().getStatusCode() == 200){
                T response = gson.fromJson(jsonStr, clazz);
                return response;
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T> T httpDelete(String url, Class<T> clazz, Map<String, String> params) {
        StringBuilder builder = new StringBuilder(url);
        if(url.contains("?") && params != null){
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.append("&");
                builder.append(entry.getKey());
                builder.append("=");
                builder.append(entry.getValue());
            }
        }else if(!url.contains("?") && params != null){
            builder.append("?");
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.append("&");
                builder.append(entry.getKey());
                builder.append("=");
                builder.append(entry.getValue());
            }
        }
        HttpDelete httpDelete = new HttpDelete(builder.toString());
        try {
            HttpResponse res = httpclient.execute(httpDelete);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>"+ url + "\r\nresponse=>" + jsonStr);
            if(res.getStatusLine().getStatusCode() == 200){
                T response = gson.fromJson(jsonStr, clazz);
                return response;
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T> T httpGet(String url, Class<T> clazz, Map<String, String> params) {
        StringBuilder builder = new StringBuilder(url);
        if(url.contains("?") && params != null){
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.append("&");
                builder.append(entry.getKey());
                builder.append("=");
                builder.append(entry.getValue());
            }
        }else if(!url.contains("?") && params != null){
            builder.append("?");
            for (Map.Entry<String, String> entry : params.entrySet()) {
                builder.append("&");
                builder.append(entry.getKey());
                builder.append("=");
                builder.append(entry.getValue());
            }
        }
        HttpGet httpGet = new HttpGet(builder.toString());
        try {
            HttpResponse res = httpclient.execute(httpGet);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>"+ url + "\r\nresponse=>" + jsonStr);
            if(res.getStatusLine().getStatusCode() == 200){
                T response = gson.fromJson(jsonStr, clazz);
                return response;
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T> T httpGet(String url, Class<T> clazz) {
        HttpGet httpGet = new HttpGet(url);
        try {
            HttpResponse res = httpclient.execute(httpGet);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>" + url + "\r\nresponse=>" + jsonStr);
            if(res.getStatusLine().getStatusCode() == 200){
                T response = gson.fromJson(jsonStr, clazz);
                return response;
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }

    public static <T> T httpPost(String url, String body, Header[] headers, Class<T> clazz) {
        HttpPost httpPost = new HttpPost(url);
        try {
            httpPost.setHeaders(headers);
            httpPost.setEntity(new StringEntity(body, "UTF-8"));
            HttpResponse res = httpclient.execute(httpPost);
            String jsonStr = EntityUtils.toString(res.getEntity(), "UTF-8");
            log.info("request=>"+ url + "\n\nbody=>" + body + "\r\nresponse=>" + jsonStr);

            if(res.getStatusLine().getStatusCode() == 200){
                T response = gson.fromJson(jsonStr, clazz);
                return response;
            }else{
                throw new BuzException(res.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BuzException(BuzEnum.REMOTE_CONNECT_ERROR);
        }
    }
}
